package cn.eeepay.framework.service.impl;

import cn.eeepay.framework.dao.AccountAddressLogDao;
import cn.eeepay.framework.dao.AccountAddrOrderDao;
import cn.eeepay.framework.dao.AccountAddressDao;
import cn.eeepay.framework.db.pagination.Page;
import cn.eeepay.framework.model.AccountAddrOrder;
import cn.eeepay.framework.model.AccountAddress;
import cn.eeepay.framework.model.AccountAddressLog;
import cn.eeepay.framework.model.JumpRouteQuotaLog;
import cn.eeepay.framework.service.AccountAddressService;
import cn.eeepay.framework.service.RouterOrgService;
import cn.eeepay.framework.service.SysDictService;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.*;

@Service
public class AccountAddressServiceImpl implements AccountAddressService {

    Logger logger = LoggerFactory.getLogger(AccountAddressServiceImpl.class);

    @Autowired
    private AccountAddressDao accountAddressDao;
    @Autowired
    private AccountAddressLogDao accountAddressLogDao;
    @Autowired
    private AccountAddrOrderDao accountAddrOrderDao;
    @Autowired
    private RouterOrgService routerOrgService;
    @Autowired
    private SysDictService sysDictService;

    @Override
    public int insert(AccountAddress accountAddress) {
        return accountAddressDao.insert(accountAddress);
    }

    @Transactional
    @Override
    public int insertExport(List<AccountAddress> accountAddressList) {
        accountAddressDao.delete();
        for (AccountAddress accountAddress : accountAddressList) {
            insert(accountAddress);
        }
        return 0;
    }

    @Override
    public int update(AccountAddress accountAddress) {
        return accountAddressDao.update(accountAddress);
    }

    @Override
    public List<AccountAddress> select(Page<AccountAddress> page) {
        List<AccountAddress> list = accountAddressDao.select(page);
        if(CollectionUtil.isNotEmpty(list)){
            for (AccountAddress accountAddress : list) {
                accountAddress.setReleaseTimeStr(DateUtil.formatTime(accountAddress.getReleaseTime()));
                accountAddress.setStartTimeStr(DateUtil.formatTime(accountAddress.getStartTime()));
                accountAddress.setEndTimeStr(DateUtil.formatTime(accountAddress.getEndTime()));
            }
        }
        return list;
    }

    @Override
    public AccountAddress findAccountAddressByAddress(String address) {
        return accountAddressDao.findAccountAddressByAddress(address);
    }

    @Override
    public void updateJoinGroupPollingStatus(Integer id, Integer status) {
        accountAddressDao.updateJoinGroupPollingStatus(id,status);
    }

    @Override
    public void updateOpenStatus(Integer id, Integer status) {
        accountAddressDao.updateOpenStatus(id,status);
    }


    @Override
    public Map<String, Object> addressMonitor(String address, String dateStart, String dateEnd, Page<AccountAddrOrder> page) {
        List<AccountAddrOrder> accountAddrOrders = accountAddrOrderDao.addressMonitor(address,dateStart,dateEnd,page);
        List<Map<String,Object>> gridMap = new ArrayList<>();
        Map<String,String> tableHeader = new HashMap<>();       //保存所有可能存在的表头
        if(CollectionUtil.isNotEmpty(accountAddrOrders)){
            for (AccountAddrOrder accountAddrOrder : accountAddrOrders) {
                String merProvince = accountAddrOrder.getMerProvince();
                Date accountDate = accountAddrOrder.getAccountDate();
                String accountDateStr = DateUtil.formatDate(accountDate);
                BigDecimal transAmount = accountAddrOrder.getTransAmount().divide(new BigDecimal("10000")).setScale(2, BigDecimal.ROUND_HALF_UP);
                List<Map<String, Object>> maps = accountAddressDao.collectAccoundAddrOrderByMerProvinceAndDate(merProvince, accountDateStr);

                Map<String,Object> map = new HashMap<>();
                map.put("merProvince",merProvince);
                map.put("transAmount",transAmount);
                map.put("accountDate",accountDateStr);

                if(CollectionUtil.isNotEmpty(maps)){
                    for (Map<String, Object> stringObjectMap : maps) {
                        if(stringObjectMap != null && stringObjectMap.size() > 0 ){
                            String jump_id = stringObjectMap.get("jump_id").toString();
                            String remark = stringObjectMap.get("remark").toString();
                            BigDecimal trans_amount = new BigDecimal(stringObjectMap.get("trans_amount").toString()).divide(new BigDecimal("10000")).setScale(2, BigDecimal.ROUND_HALF_UP);
                            map.put(jump_id,trans_amount);
                            String filedName = jump_id+"("+remark+")跑量金额(万)";
                            tableHeader.put(jump_id,filedName);
                        }
                    }
                }
                gridMap.add(map);           //将数据保存
            }
        }
        Map<String,Object> result = new HashMap<>();
        result.put("gridData",gridMap);
        result.put("tableHeader",tableHeader);
        return result;
    }

    @Override
    public Map<String, Object> addressMonitorExport(String address, String dateStart, String dateEnd, Page<AccountAddrOrder> page) {
        List<AccountAddrOrder> accountAddrOrders = accountAddrOrderDao.addressMonitor(address,dateStart,dateEnd,page);
        Map<String,String> tableHeader = new HashMap<>();       //保存所有可能存在的动态表头
        List<Map<String,String>> data = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(accountAddrOrders)){
            for (AccountAddrOrder accountAddrOrder : accountAddrOrders) {
                String merProvince = accountAddrOrder.getMerProvince();
                Date accountDate = accountAddrOrder.getAccountDate();
                String accountDateStr = DateUtil.formatDate(accountDate);
                BigDecimal transAmount = accountAddrOrder.getTransAmount();
                List<Map<String, Object>> maps = accountAddressDao.collectAccoundAddrOrderByMerProvinceAndDate(merProvince, accountDateStr);

                Map<String,String> map = new HashMap<>();
                map.put("merProvince",merProvince);
                map.put("transAmount",transAmount.toString());
                map.put("accountDate",accountDateStr);

                if(CollectionUtil.isNotEmpty(maps)){
                    for (Map<String, Object> stringObjectMap : maps) {
                        if(stringObjectMap != null && stringObjectMap.size() > 0 ){
                            String jump_id = stringObjectMap.get("jump_id").toString();
                            String remark = stringObjectMap.get("remark").toString();
                            BigDecimal trans_amount = new BigDecimal(stringObjectMap.get("trans_amount").toString());
                            map.put(jump_id,trans_amount.toString());
                            String filedName = jump_id+"("+remark+")跑量金额(元)";
                            tableHeader.put(jump_id,filedName);
                        }
                    }
                }
                data.add(map);           //将数据保存
            }
        }

        //遍历所有数据，校验是否存在动态字段，如果不存在则补充
        for (Map<String, String> datum : data) {
            Iterator<Map.Entry<String, String>> iterator = tableHeader.entrySet().iterator();
            while(iterator.hasNext()){
                Map.Entry<String, String> next = iterator.next();
                String key = next.getKey();
                if(StrUtil.isBlank(datum.get(key))){
                    datum.put(key,"");
                }
            }
        }

        List<String> cols = new ArrayList<>();
        cols.add("merProvince");
        cols.add("transAmount");
        cols.add("accountDate");
        List<String> colsName = new ArrayList<>();
        colsName.add("注册地");
        colsName.add("已跑量金额(元)");
        colsName.add("日期");

        Iterator<Map.Entry<String, String>> iterator = tableHeader.entrySet().iterator();
        while(iterator.hasNext()){
            Map.Entry<String, String> next = iterator.next();
            String key = next.getKey();
            String value = next.getValue();
            cols.add(key);
            colsName.add(value);
        }

        Map<String,Object> result = new HashMap<>();
        result.put("data",data);
        result.put("cols",cols);
        result.put("colsName",colsName);
        return result;
    }

    @Override
    public Map<String, Object> accountAddressMonitor(String address, String dateStart, String dateEnd, Page<AccountAddrOrder> page) {
        List<AccountAddrOrder> accountAddrOrders = accountAddrOrderDao.accountAddressMonitor(address, dateStart, dateEnd,page);
        List<Map<String,Object>> gridMap = new ArrayList<>();
        Map<String,String> tableHeader = new HashMap<>();       //保存所有可能存在的表头
        String today = DateUtil.today();
        if(CollectionUtil.isNotEmpty(accountAddrOrders)){
            for (AccountAddrOrder accountAddrOrder : accountAddrOrders) {
                String accountDate = DateUtil.formatDate(accountAddrOrder.getAccountDate());
                BigDecimal totalAmount = BigDecimal.ZERO;
                if(accountDate.equals(today)){           //查当天
                    AccountAddress accountAddress = accountAddressDao.findAccountAddressByAddress(accountAddrOrder.getAccountAddress());
                    if(accountAddress != null){
                        totalAmount = accountAddress.getTotalAmount();
                    }
                }else{
                    AccountAddressLog accountAddressLog = accountAddressLogDao.findAccountAddress(accountAddrOrder.getAccountAddress(),accountDate);
                    if(accountAddressLog != null){
                        totalAmount = accountAddressLog.getCountQuota();
                    }
                }
                accountAddrOrder.setCountQuota(totalAmount);        //总额度
                BigDecimal surplusQuota = accountAddrOrder.getCountQuota().subtract(accountAddrOrder.getTransAmount());     //剩余额度
                accountAddrOrder.setSurplusQuota(surplusQuota);
                NumberFormat numberFormat = NumberFormat.getInstance();
                numberFormat.setMaximumFractionDigits(2);
                String result = "0%";
                if(accountAddrOrder.getCountQuota().compareTo(BigDecimal.ZERO) > 0){
                    result = numberFormat.format(accountAddrOrder.getTransAmount().floatValue() / accountAddrOrder.getCountQuota().floatValue() * 100);
                    if(!result.contains("%")){
                        result = result+"%";
                    }
                }
                accountAddrOrder.setUsePercent(result);        //使用百分比
            }
            for (AccountAddrOrder accountAddrOrder : accountAddrOrders) {
                Date accountDate = accountAddrOrder.getAccountDate();
                String accountAddress = accountAddrOrder.getAccountAddress();
                String accountDateStr = DateUtil.formatDate(accountDate);
                BigDecimal transAmount = accountAddrOrder.getTransAmount().divide(new BigDecimal("10000")).setScale(2, BigDecimal.ROUND_HALF_UP);
                BigDecimal countQuota = accountAddrOrder.getCountQuota().divide(new BigDecimal("10000")).setScale(2, BigDecimal.ROUND_HALF_UP);
                BigDecimal surplusQuota = accountAddrOrder.getSurplusQuota().divide(new BigDecimal("10000")).setScale(2, BigDecimal.ROUND_HALF_UP);
                List<Map<String, Object>> maps = accountAddressDao.collectAccoundAddrOrderByAccountAddressAndDate(accountAddress, accountDateStr);

                Map<String,Object> map = new HashMap<>();
                map.put("accountAddress",accountAddress);
                map.put("countQuota",countQuota);
                map.put("transAmount",transAmount);
                map.put("surplusQuota",surplusQuota);
                map.put("usePercent",accountAddrOrder.getUsePercent());
                map.put("accountDate",accountDateStr);
                map.put("merProvince",accountAddrOrder.getMerProvince());

                if(CollectionUtil.isNotEmpty(maps)){
                    for (Map<String, Object> stringObjectMap : maps) {
                        if(stringObjectMap != null && stringObjectMap.size() > 0 ){
                            String jump_id = stringObjectMap.get("jump_id").toString();
                            String remark = stringObjectMap.get("remark").toString();
                            BigDecimal trans_amount = new BigDecimal(stringObjectMap.get("trans_amount").toString()).divide(new BigDecimal("10000")).setScale(2, BigDecimal.ROUND_HALF_UP);
                            map.put(jump_id,trans_amount);
                            String filedName = jump_id+"("+remark+")跑量金额(万)";
                            tableHeader.put(jump_id,filedName);
                        }
                    }
                }
                gridMap.add(map);           //将数据保存
            }
        }

        Map<String,Object> result = new HashMap<>();
        result.put("gridData",gridMap);
        result.put("tableHeader",tableHeader);
        return result;
    }

    @Override
    public Map<String, Object> accountAddressMonitorExport(String address, String dateStart, String dateEnd, Page<AccountAddrOrder> page) {
        List<AccountAddrOrder> accountAddrOrders = accountAddrOrderDao.accountAddressMonitor(address, dateStart, dateEnd,page);
        List<Map<String,String>> data = new ArrayList<>();
        Map<String,String> tableHeader = new HashMap<>();       //保存所有可能存在的表头
        String today = DateUtil.today();
        if(CollectionUtil.isNotEmpty(accountAddrOrders)){
            for (AccountAddrOrder accountAddrOrder : accountAddrOrders) {
                String accountDate = DateUtil.formatDate(accountAddrOrder.getAccountDate());
                BigDecimal totalAmount = BigDecimal.ZERO;
                if(accountDate.equals(today)){           //查当天
                    AccountAddress accountAddress = accountAddressDao.findAccountAddressByAddress(accountAddrOrder.getAccountAddress());
                    if(accountAddress != null){
                        totalAmount = accountAddress.getTotalAmount();
                    }
                }else{
                    AccountAddressLog accountAddressLog = accountAddressLogDao.findAccountAddress(accountAddrOrder.getAccountAddress(),accountDate);
                    if(accountAddressLog != null){
                        totalAmount = accountAddressLog.getCountQuota();
                    }
                }
                accountAddrOrder.setCountQuota(totalAmount);        //总额度
                BigDecimal surplusQuota = accountAddrOrder.getCountQuota().subtract(accountAddrOrder.getTransAmount());     //剩余额度
                accountAddrOrder.setSurplusQuota(surplusQuota);
                NumberFormat numberFormat = NumberFormat.getInstance();
                numberFormat.setMaximumFractionDigits(2);
                String result = "0%";
                if(accountAddrOrder.getCountQuota().compareTo(BigDecimal.ZERO) > 0){
                    result = numberFormat.format(accountAddrOrder.getTransAmount().floatValue() / accountAddrOrder.getCountQuota().floatValue() * 100);
                    if(!result.contains("%")){
                        result = result+"%";
                    }
                }
                accountAddrOrder.setUsePercent(result);        //使用百分比
            }

            for (AccountAddrOrder accountAddrOrder : accountAddrOrders) {
                Date accountDate = accountAddrOrder.getAccountDate();
                String accountAddress = accountAddrOrder.getAccountAddress();
                String accountDateStr = DateUtil.formatDate(accountDate);
                BigDecimal transAmount = accountAddrOrder.getTransAmount();
                BigDecimal countQuota = accountAddrOrder.getCountQuota();
                BigDecimal surplusQuota = accountAddrOrder.getSurplusQuota();
                List<Map<String, Object>> maps = accountAddressDao.collectAccoundAddrOrderByAccountAddressAndDate(accountAddress, accountDateStr);

                Map<String,String> map = new HashMap<>();
                map.put("accountAddress",accountAddress);
                map.put("countQuota",countQuota.toString());
                map.put("transAmount",transAmount.toString());
                map.put("surplusQuota",surplusQuota.toString());
                map.put("usePercent",accountAddrOrder.getUsePercent());
                map.put("accountDate",accountDateStr);

                if(CollectionUtil.isNotEmpty(maps)){
                    for (Map<String, Object> stringObjectMap : maps) {
                        if(stringObjectMap != null && stringObjectMap.size() > 0 ){
                            String jump_id = stringObjectMap.get("jump_id").toString();
                            String remark = stringObjectMap.get("remark").toString();
                            BigDecimal trans_amount = new BigDecimal(stringObjectMap.get("trans_amount").toString());
                            map.put(jump_id,trans_amount.toString());
                            String filedName = jump_id+"("+remark+")跑量金额(元)";
                            tableHeader.put(jump_id,filedName);
                        }
                    }
                }
                data.add(map);           //将数据保存
            }
        }

        //遍历所有数据，校验是否存在动态字段，如果不存在则补充
        for (Map<String, String> datum : data) {
            Iterator<Map.Entry<String, String>> iterator = tableHeader.entrySet().iterator();
            while(iterator.hasNext()){
                Map.Entry<String, String> next = iterator.next();
                String key = next.getKey();
                if(StrUtil.isBlank(datum.get(key))){
                    datum.put(key,"");
                }
            }
        }

        List<String> cols = new ArrayList<>();
        cols.add("accountAddress");
        cols.add("countQuota");
        cols.add("transAmount");
        cols.add("surplusQuota");
        cols.add("usePercent");
        cols.add("accountDate");


        List<String> colsName = new ArrayList<>();
        colsName.add("账单地");
        colsName.add("总额度(元)");
        colsName.add("已使用额度(元)");
        colsName.add("剩余额度(元)");
        colsName.add("使用占比(%)");
        colsName.add("日期");

        Iterator<Map.Entry<String, String>> iterator = tableHeader.entrySet().iterator();
        while(iterator.hasNext()){
            Map.Entry<String, String> next = iterator.next();
            String key = next.getKey();
            String value = next.getValue();
            cols.add(key);
            colsName.add(value);
        }

        Map<String,Object> result = new HashMap<>();
        result.put("data",data);
        result.put("cols",cols);
        result.put("colsName",colsName);
        return result;
    }

    @Override
    public List<AccountAddrOrder> addressMonitorDetail(String address, String date) {
        return accountAddrOrderDao.addressMonitorDetail(address,date);
    }

    @Override
    public List<AccountAddrOrder> accountAddressMonitorDetail(String address, String date) {
        return accountAddrOrderDao.accountAddressMonitorDetail(address,date);
    }

    //账单地信息迁移到log
    @Transactional
    @Override
    public void addrOrderMoveAccountAddressLog(String accountDate) {
        List<AccountAddressLog> accountAddressLogs = accountAddressDao.collectAccountAddrOrder(accountDate);
        if(CollectionUtil.isNotEmpty(accountAddressLogs)){
            for (AccountAddressLog accountAddressLog : accountAddressLogs) {
                AccountAddress address = accountAddressDao.findAccountAddressByAddress(accountAddressLog.getAddress());
                if(address != null ){
                    BigDecimal totalAmount = address.getTotalAmount();
                    accountAddressLog.setCountQuota(totalAmount);
                    accountAddressLog.setCreateTime(new Date());
                    accountAddressLog.setLocalUsed(address.getLocalUsed());
                    accountAddressLog.setOtherUsed(address.getOtherUsed());
                    accountAddressLog.setReleaseTime(address.getReleaseTime());
                    accountAddressLog.setReservedAmount(address.getReservedAmount());
                    accountAddressLog.setAddressType(address.getAddressType());
                    accountAddressLogDao.insert(accountAddressLog);
                }
            }
        }
    }

    @Override
    public AccountAddress findById(Integer id) {
        return accountAddressDao.findById(id);
    }

    @Override
    public List<AccountAddress> findAccountAddressByDateAndAccountAddressAndType(String dateStart,String dateEnd, String accountAddress, Integer type, Page<AccountAddress> page) {
        List<AccountAddress> accountAddressList = null;

        //查今天
        String today = DateUtil.today();
        if(dateStart.equals(today) || dateEnd.equals(today)){
            accountAddressList = accountAddressDao.findToDayAccountAddressByDateAndAccountAddressAndType(accountAddress, type, page);
            if(CollectionUtil.isNotEmpty(accountAddressList)){
                for (AccountAddress address : accountAddressList) {
                    String releaseTimeStr = DateUtil.formatTime(address.getReleaseTime());
                    address.setReleaseTimeStr(releaseTimeStr);
                    address.setAccountDate(new Date());
                }
            }
        }else{          //查历史
            accountAddressList = accountAddressDao.findHistoryAccountAddressByDateAndAccountAddressAndType(dateStart,dateEnd,accountAddress,type,page);
        }
        return accountAddressList;
    }


}
